package com.kmxd.ams.app.license;

import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.kmxd.ams.client.license.IConfLicenseSvc;
import com.kmxd.ams.client.license.dto.ConfLicenseEditDTO;
import com.kmxd.ams.client.system.ISysCropSvc;
import com.kmxd.ams.core.common.constant.CacheConst;
import com.kmxd.ams.core.common.constant.Constants;
import com.kmxd.ams.core.common.constant.ErrorCode;
import com.kmxd.ams.core.exception.BizTipException;
import com.kmxd.ams.core.exception.LogInfo;
import com.kmxd.ams.core.license.constant.LicenseConst;
import com.kmxd.ams.core.license.verify.config.LicenseVerifyProperties;
import com.kmxd.ams.core.license.verify.model.LicenseAuthInfo;
import com.kmxd.ams.core.license.verify.model.LicenseVerifyManager;
import com.kmxd.ams.core.license.verify.service.LicenseVerifyService;
import com.kmxd.ams.core.util.SecurityUtil;
import com.kmxd.ams.infra.license.entity.ConfLicense;
import com.kmxd.ams.infra.license.mapper.ConfLicenseMapper;
import com.kmxd.ams.infra.system.entity.SysCrop;
import java.util.List;
import java.util.Map;
import lombok.AllArgsConstructor;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.retry.annotation.Backoff;
import org.springframework.retry.annotation.Retryable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * 授权信息表 服务实现类
 *
 * @author ZuoLG
 * @since 2023-05-12
 */
@Service
@AllArgsConstructor
@CacheConfig(cacheNames = CacheConst.CACHE_PREFIX_LICENSE)
public class ConfLicenseSvcImpl extends ServiceImpl<ConfLicenseMapper, ConfLicense>
    implements IConfLicenseSvc {
  private final LicenseVerifyService licenseVerifyService;
  private final ISysCropSvc sysCropSvc;

  @Override
  public void uninstallAuth() throws Exception {
    ConfLicense confLicense = getLicenseInfo();
    LicenseVerifyProperties properties = new LicenseVerifyProperties();
    if (ObjectUtil.isNotEmpty(confLicense)) {
      properties.setLicenseCode(confLicense.getRegCode());
    }
    LicenseVerifyManager licenseVerifyManager = new LicenseVerifyManager();
    licenseVerifyManager.uninstall(properties.getVerifyParam());
  }

  @Override
  @Cacheable(keyGenerator = "myKeyGenerator")
  public ConfLicense getLicenseInfo() {
    LambdaQueryWrapper<ConfLicense> queryWrapper = Wrappers.lambdaQuery();
    List<ConfLicense> list = this.baseMapper.selectList(queryWrapper);
    return list.stream().findFirst().orElse(null);
  }

  @CacheEvict(allEntries = true)
  @Override
  @Transactional(rollbackFor = Exception.class)
  public void licenseAuth(ConfLicenseEditDTO req) throws Exception {
    if (ObjectUtil.isEmpty(req.getRegCode())) {
      throw new BizTipException(LogInfo.newInstance(), ErrorCode.NOT_FOUND, "授权码不能为空！");
    }
    ConfLicense license = getLicenseInfo();
    if (ObjectUtil.isEmpty(license)) {
      license = new ConfLicense();
      license.setId(IdWorker.getId());
    }
    license.setRegCode(req.getRegCode());
    license.setComputerCode(req.getComputerCode());
    license.setFondsId(SecurityUtil.getFondsId());
    license.setRegUser(SecurityUtil.getUsername());
    license.setRegFlag(1);
    license.setRegType(1);
    license.setVersion(1);
    // 定义重试器并配置
    try {
      updateLicense(req);
    } catch (Exception e) {
      log.error(e.getMessage(), e);
      throw new BizTipException(
          LogInfo.newInstance(), ErrorCode.NOT_FOUND, "授权错误 ，请检查授权码或刷新当前页面重试！");
    }

    LicenseAuthInfo authInfo = licenseVerifyService.licenseAuthInfo();
    if (authInfo != null) {
      Map<String, Object> params = authInfo.getParams();
      if (!params.isEmpty()) {
        Integer fondsNum = MapUtil.getInt(params, LicenseConst.FONDS_NUM);
        license.setCompanyNum(fondsNum);
      }
      license.setPeriod(authInfo.getAfterTime());
      license.setRegTime(authInfo.getBeginTime());
    }
    // 查询默认单位，修改默认单位的授权数量

    List<SysCrop> crops = sysCropSvc.selectListAll();
    SysCrop crop =
        crops.stream()
            .filter(x -> ObjectUtil.equal(x.getId(), Constants.DEFAULT_CROP_ID))
            .findFirst()
            .orElse(null);
    if (ObjectUtil.isNotNull(crop)) {
      crop.setSubCropNum(
          ObjectUtil.isNotEmpty(license.getCompanyNum())
              ? Long.parseLong(license.getCompanyNum().toString())
              : 1L);
      sysCropSvc.updateById(crop);
    }
    this.saveOrUpdate(license);
  }

  /**
   * 抽离更新授权
   *
   * @param req
   * @throws Exception
   */
  @Retryable(
      value = Exception.class,
      maxAttempts = 2,
      backoff = @Backoff(delay = 2000, multiplier = 1.5))
  private boolean updateLicense(ConfLicenseEditDTO req) throws Exception {
    licenseVerifyService.updateLicense(req.getRegCode());
    LicenseAuthInfo authInfo = licenseVerifyService.licenseAuthInfo();
    return authInfo != null;
  }
}
